﻿using System;
using System.Drawing;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using CoreLib;

using CoreLib.Plugins;
namespace CoreLib
{
   public class C3DModel:DrawablePlugin
    {
       [System.Xml.Serialization.XmlIgnore]
        private CMaterial material;

       public CMaterial Material
       {
           get { return material; }
           set { material = value; }
       }

       
        string buildError;
        Game game;
        public C3DModel(Game gameparameter)
            : base(gameparameter)
       {
           game = gameparameter;
           RotationMatrix = Matrix.Identity;
          PositionMatrix = Matrix.Identity;

          PluginName = "3DModel";
          PluginDescription = "A 3D model.";
          PluginCommands plugincommand = new PluginCommands((Bitmap)Image.FromFile(System.Environment.CurrentDirectory + "/plugins/3Dmodelbutton.png"),"3D Model");
          plugincommand.PluginImage = (Bitmap)Image.FromFile(System.Environment.CurrentDirectory + "/plugins/3Dmodelbutton.png");
          PluginCommands.Add(plugincommand);       
        }
        public override void Draw(GameTime gameTime)
        {
            try
            {
                if (Material != null)
                {
                    DrawWithShaders();
                }
                else
                {
                    DrawModel();
                }
            }



            catch (Exception e)
            {

                throw e;
            }
        }
        public bool DrawWithShaders()
        {
            try
            {
                Matrix matrix = new Matrix();
                matrix =Engine.CurrentCamera.View;
                foreach (ModelMesh mesh in RenderModel.Meshes)
                {
                    Material.MaterialShader.Parameters["view"].SetValue(matrix);
                    Material.MaterialShader.Parameters["projection"].SetValue(CCameraComponent.Projection);
                    Material.Draw(mesh, Transforms[RenderModel.Meshes[0].ParentBone.Index] * PositionMatrix * RotationMatrix * ScaleMatrix);
                }
            }
            catch (Exception e)
            {

                throw e;
                return false;
            }
            return true;
        }
        public void DrawModel()
        {



            // Draw the model.
            try
            {
                if (RenderModel == null) return;
                RenderModel.CopyAbsoluteBoneTransformsTo(Transforms);

                foreach (ModelMesh mesh in RenderModel.Meshes)
                {
                    // foreach (Effect effect in mesh.Effects)
                    // {
                    //Transformations.world = transforms[mesh.ParentBone.Index] *Transformations.matposition* Transformations.rotation;

                    // effect.Parameters["World"].SetValue(Transformations.world);
                    // Vector3 up = Vector3.Up;
                    // CCamera.view = Matrix.CreateLookAt(new Vector3(0, 5, 0), new Vector3(1, 5, 0), up);
                    // effect.Parameters["View"].SetValue(CCamera.view);
                    // effect.Parameters["Projection"].SetValue(Engine.projection);


                    //}
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        World = Transforms[mesh.ParentBone.Index] * PositionMatrix *RotationMatrix * ScaleMatrix;

                        effect.EnableDefaultLighting();
                        effect.World =World;
                        effect.View = Engine.CurrentCamera.View;
                        effect.Projection = CCameraComponent.Projection;
                        effect.PreferPerPixelLighting = true;
                        effect.SpecularPower = 16;
                       
                    }
                    mesh.Draw();

                }
            }
            catch (Exception)
            {

                throw;
            }
        }
        protected override void LoadContent()
        {
            try
            {
               // if (game.Components.Contains(this) == false)
                {
                    LoadModel(AssetName);
                    
                }
            }
            catch (Exception)
            {

            }
       
        }
        public void LoadModel(string assetName)
        {
            if (assetName == "" || assetName == null) return;
            RenderModel =game.Content.Load<Model>(assetName);
            Transforms = new Matrix[RenderModel.Bones.Count];
    
            AssetName = assetName;

          
        }

        public override void Create()
        {
            OpenFileDialog openfiledialog = new OpenFileDialog();
            openfiledialog.ShowDialog();
           AssetName = openfiledialog.SafeFileName.Replace(".xnb","");
           Load();
           PositionVector3 = Engine.CurrentCamera.PositionVector3;
        }
        public Engine.CollideResult Collide(Engine.CollideType CollideType)
        {
            Engine.CollideResult res = new Engine.CollideResult();
           // CInterSections Intersections = new CInterSections();
            C3DModel CollideModel = new C3DModel(game);
            Model CollideMesh;
            Engine.CollideObject CollideObject = new Engine.CollideObject();
            Matrix SourceMatrix = new Matrix();
            Matrix CollideMatrix = new Matrix();

            switch (CollideType)
            {
                // Bounding sphere based picking
                case Engine.CollideType.BoundingSphere:
                    //cursorRay = cursor.CalculateCursorRay(CCameraComponent.Projection, CCamera.View);
                    foreach (GameComponent comp in game.Components)
                    {
                       // if (comp is C3DModel & comp != this) Need to redo
                        //{

                            CollideModel = (C3DModel)comp;
                            CollideMesh = CollideModel.RenderModel;
                            CollideMatrix = CollideModel.PositionMatrix * CollideModel.RotationMatrix * CollideModel.ScaleMatrix;
                            SourceMatrix = PositionMatrix * RotationMatrix * ScaleMatrix;
                            CollideObject = Engine.CollideObject.Model;
                           // res = Intersections.CollideBoundingSphere(this.RenderModel, CollideModel.RenderModel, CollideMatrix, SourceMatrix,
                            //          CollideModel.Transforms, CollideObject);
                       // }


                    }

                    break;
                case Engine.CollideType.Triangle:
                    //cursorRay = cursor.CalculateCursorRay(CCameraComponent.Projection, CCamera.View);

                    foreach (GameComponent comp in game.Components)
                    {
                       // if (comp is C3DModel & comp != this) Need to redo
                        //{

                            CollideModel = (C3DModel)comp;
                            CollideMesh = CollideModel.RenderModel;
                            CollideMatrix = CollideModel.PositionMatrix * CollideModel.RotationMatrix * CollideModel.ScaleMatrix;
                            SourceMatrix = PositionMatrix * RotationMatrix * ScaleMatrix;
                            CollideObject = Engine.CollideObject.Model;
                            // Ray CollideRay = new Ray(CollideModel.mPosition,CollideModel.GetRotationVector());

                            Ray CollideRay = new Ray(CollideModel.PositionVector3, new Vector3(0, 0, -1));
                         //   res = Intersections.CollideVertex(CollideRay, this.RenderModel, CollideModel.RenderModel, CollideMatrix, SourceMatrix, CollideModel.RenderModel.Tag, this.RenderModel.Tag, CollideObject);
                        //}


                    }

                    break;

                default:
                    break;
            }

            if (res.Hit)
            {
               // res.Model =(CoreLib.C3DModel)CollideModel;
                res.HitPosition = CollideModel.PositionVector3;
                res.CollideObjectType = CollideObject;
                // CEngine.PickResults.Add(res);
            }
            //res = Intersections.GetNearestPick();
            return res;
        }
     
        }
    }

